package dataprocess;

import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.util.Scanner;
import java.io.IOException;

import triviaException.TriviaException;
import database.Highscore;
import database.Score;

/**
 * Procesamiento de los datos de puntaje, nexo entre la base de datos
 * de puntaje y los archivos en disco.
 *
 */

public class HighScoreDb {
	private FileReader[] aFile;
	private String[] filename = {"data/HighScores/easy.hs", 
								 "data/HighScores/medium.hs"
								 , "data/HighScores/hard.hs"};
	
	/**
	 * Crea una instancia HighScoreDb, inicializando instancias
	 * de FileReader pra cada archivo de puntajes,
	 * @throws FileNotFoundException - Si no existen los archivos
	 */
	
	public HighScoreDb() throws FileNotFoundException {
		super();
		int i;
		
		aFile = new FileReader[filename.length];
		
		for (i = 0 ; i < aFile.length ; i++) 
			aFile[i] = new FileReader(filename[i]);
	} 

	/**
	 * Salva la base de datos de puntajes, diferenciada por categoria
	 * @param hscores - Base de datos de puntaje
	 * @param level - Categoria de los puntajes (nivel fácil, medio, dificil)
	 * @throws IOException - Si no pudo salvar los puntajes en archivo.
	 */
	
	public void saveHighScoresToFile(Highscore hscores, int level) throws IOException {
		final Score[] scores;
		
			FileWriter output = new FileWriter(filename[level]);
			scores = hscores.getHighScores();
			
			for (Score singlescore : scores) {
				output.write(singlescore.toString());
			}
			output.close();
	}
	
	/**
	 * Carga la base de datos de puntajes, diferenciada por categoria
	 * @param level - Categoria de los puntajes (nivel fácil, medio, dificil) a cargar
	 * @throws NumberFormatException - Si los puntajes leídos son inválidos
	 * @throws TriviaException - Si el archivo de puntajes está corrupto
	 */
	
	public Highscore loadHighScoresFromFile(int level) throws NumberFormatException, TriviaException { 
															  
		Highscore hscores = new Highscore();
		String strscore;
		int line = 1;
		String[] splitscore = null;
		Scanner scorescan = null;
		scorescan = new Scanner(aFile[level]);
		
		/*
		 * Mientas haya puntajes en el archivo, los lee verificando
		 * mediante una expresión regular que sean correctos 
		 * ("string" + "   " + puntaje(digitos))
		 */
		while (scorescan.hasNextLine()) {
			strscore = scorescan.nextLine();
			if (!strscore.equals("")) {
				if ( !strscore.matches("[^ ]{1,20}\\s\\d{1,3}$")) {
					System.err.println("Error en "+ filename[level]+":"+line);
					throw new NumberFormatException();
				}
				line++;
					
	
				splitscore = strscore.split("\\s+");
				// Siempre splitscore sera un String[] de dos elementos
				// pues el formato de strscore es fijo.
				Score singlescore = new Score(splitscore[0], Integer.valueOf(splitscore[1]));
				hscores.setHighScore(singlescore);
			}
		}
		
		scorescan.close();
		
		return hscores;
		
	}

	/**
	 * Cierra todas los archivos referenciados por las instancias
	 * FileReader
	 * @see java.lang.Object#finalize()
	 */
	@Override
	protected void finalize() throws Throwable {
		
		super.finalize();
		
		for (FileReader auxfile : aFile) {
			auxfile.close();
		}
	}
	
	
}
